#include <iostream>
#include <type_traits>
//参考文档: https://cplusplus.com/reference/type_traits/enable_if/
struct Base {

};

struct Derived:Base{

};
struct Other {

};

// std::enable_if可以让模板的相关参数在编译时校验，如果不满足需求那么就编译不过
template <typename T>
typename std::enable_if<std::is_base_of<Base,T>::value || std::is_base_of<Other, T>::value, int>::type 
calculateResult(T) {
    return 120;
}

template <typename T,
          typename = typename std::enable_if<std::is_integral<T>::value, T>::type>
bool is_even(T i) {
    return !bool(i % 2);
}

int type_traits_main()
{
    using namespace std;
    cout << "is_base_of: " << endl;
    cout << "int, int: " << std::is_base_of<int, int>::value << endl;
    cout << "Base, Base: " << std::is_base_of<Base, Base>::value << endl;
    cout << "Base, Derived: " << std::is_base_of<Base, Derived>::value << endl;
    cout << "Base, const Derived: " << std::is_base_of<Base, const Derived>::value << endl;
    cout << "Derived, Base: " << std::is_base_of<Derived, Base>::value << endl;

    cout << "calculateResult: Derived: " << calculateResult(Derived()) << endl;
    cout << "calculateResult: Other: " << calculateResult(Other()) << endl;

    double a = 2.0;
    int b = 2;
    cout << "is_even: " << is_even(b) << endl;
    return 0;
}
